package org.the.gsdo.client;

import org.the.gsdo.client.InputPanel.InputActivity;
import org.the.gsdo.client.InputPanel.InputPlace;
import org.the.gsdo.client.ResponsePanel.ResponseActivity;
import org.the.gsdo.client.ResponsePanel.ResponsePlace;

import com.google.gwt.activity.shared.Activity;
import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.gwt.place.shared.WithTokenizers;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.ui.RootPanel;
import com.gwtplatform.dispatch.client.DefaultDispatchAsync;
import com.gwtplatform.dispatch.client.actionhandler.DefaultClientActionHandlerRegistry;
import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.dispatch.shared.SecurityCookieAccessor;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class GwtSpring implements EntryPoint {

	// http://www.jhkuperus.nl/articles/java/gwt-dynamically-changing-css-styles/

	private CenterPanel center;
	private com.google.web.bindery.event.shared.EventBus eventBus;
	private PlaceController placeController;
	private ActivityMapper activityMapper;
	private ActivityManager activityManager;
	private PPlaceHistoryMapper historyMapper;

	// GwtSpring.gwt.xml ...

	/**
	 * This is the entry point method.
	 */
	@Override
	public void onModuleLoad() {
		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
    		@Override
    		public void onUncaughtException(Throwable throwable) {
    			throwable.printStackTrace();
    		}
    	});
		eventBus = new com.google.web.bindery.event.shared.SimpleEventBus();
		placeController = new PlaceController(eventBus);
		activityMapper = new PActivityMapper(placeController);
		activityManager = new ActivityManager(activityMapper, eventBus);
		historyMapper = GWT.create(PPlaceHistoryMapper.class);
		//
		PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
		historyHandler.register(placeController, eventBus, new InputPanel.InputPlace());
		//
		center = new CenterPanel();
		RootPanel.get().add(center);
		activityManager.setDisplay(center);
		historyHandler.handleCurrentHistory();
//		placeController.goTo(new InputPlace());
	}

	@WithTokenizers( {
		InputPanel.InputPlace.Tokenizer.class,
		ResponsePanel.ResponsePlace.Tokenizer.class } )
	public static interface PPlaceHistoryMapper extends PlaceHistoryMapper {

	}

	public static class PActivityMapper implements ActivityMapper {

		private PlaceController placeController;
		private InputActivity inputActivity = new InputActivity();
		private ResponseActivity responseActivity = new ResponseActivity();

		public PActivityMapper(PlaceController placeController) {
			this.placeController = placeController;
		}

		@Override
		public Activity getActivity(Place place) {
			if (place instanceof InputPlace) {
				return inputActivity.with(placeController).nextPlace(place);
			} else if (place instanceof ResponsePlace) {
				return responseActivity.with(placeController).nextPlace(place);
			}
			return null;
		}
	}

	public static class ServiceLocator {
		private static DispatchAsync dispatchAsync;
		public static DispatchAsync getService() {
			if (dispatchAsync == null) {
				dispatchAsync = new DefaultDispatchAsync(
						new com.gwtplatform.dispatch.client.DefaultExceptionHandler(),
						new SecurityCookieAccessor() {
							@Override
							public String getCookieContent() {
								return Cookies.getCookie("JSESSIONID");
							}
						},
						new DefaultClientActionHandlerRegistry());
			}
			return dispatchAsync;
		}
	}

}
